package com.example.rpcdemo.registry;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class ServiceRegistry {
    private static final ServiceRegistry INSTANCE = new ServiceRegistry();
    private final Map<String, Set<ServiceInstance>> registry = new ConcurrentHashMap<>();
    private final Map<String, Set<ServiceInstance>> interfaceToInstance = new ConcurrentHashMap<>();
    
    // 私有构造器 - 防止外部实例化
    private ServiceRegistry() {}
    
    // 获取单例实例 - 静态常量方式，线程安全
    public static ServiceRegistry getInstance() {
        return INSTANCE;
    }
    
    public void register(String serviceName, String interfaceName, String host, int port) {
        ServiceInstance instance = new ServiceInstance(serviceName, interfaceName, host, port);
        
        registry.computeIfAbsent(serviceName, k -> ConcurrentHashMap.newKeySet()).add(instance);
        interfaceToInstance.computeIfAbsent(interfaceName, k -> ConcurrentHashMap.newKeySet()).add(instance);
        
        System.out.println("Service registered: " + serviceName + " -> " + host + ":" + port);
    }
    
    public void unregister(String serviceName, String host, int port) {
        Set<ServiceInstance> instances = registry.get(serviceName);
        if (instances != null) {
            instances.removeIf(instance -> instance.getHost().equals(host) && instance.getPort() == port);
        }
        
        for (Map.Entry<String, Set<ServiceInstance>> entry : interfaceToInstance.entrySet()) {
            entry.getValue().removeIf(instance -> 
                instance.getHost().equals(host) && instance.getPort() == port);
        }
    }
    
    public ServiceInstance discover(String serviceName) {
        Set<ServiceInstance> instances = registry.get(serviceName);
        if (instances == null || instances.isEmpty()) {
            throw new RuntimeException("No instances found for service: " + serviceName);
        }
        
        List<ServiceInstance> instanceList = new ArrayList<>(instances);
        return instanceList.get(new Random().nextInt(instanceList.size()));
    }
    
    public ServiceInstance discoverByInterface(String interfaceName) {
        Set<ServiceInstance> instances = interfaceToInstance.get(interfaceName);
        if (instances == null || instances.isEmpty()) {
            throw new RuntimeException("No instances found for interface: " + interfaceName);
        }
        
        List<ServiceInstance> instanceList = new ArrayList<>(instances);
        return instanceList.get(new Random().nextInt(instanceList.size()));
    }
    
    public List<ServiceInstance> getAllInstances(String serviceName) {
        Set<ServiceInstance> instances = registry.get(serviceName);
        return instances != null ? new ArrayList<>(instances) : Collections.emptyList();
    }
    
    public List<ServiceInstance> getAllInstancesByInterface(String interfaceName) {
        Set<ServiceInstance> instances = interfaceToInstance.get(interfaceName);
        return instances != null ? new ArrayList<>(instances) : Collections.emptyList();
    }
    
    public Map<String, Set<ServiceInstance>> getRegistry() {
        return new HashMap<>(registry);
    }
}